# -*- coding: utf-8 -*-

# Trac imports.
from trac.core import Component, implements
from trac.env import IEnvironmentSetupParticipant
from trac.config import ListOption


# Last discussion database shcema version.
last_db_version = 6


class DiscussionInit(Component):
    """
        Initialise database and environment for discussion component.
    """
    implements(IEnvironmentSetupParticipant)

    additional_options = ListOption('discussion', 'additional_options', default='',
                              doc='additional options to upgrade environment')

    # IEnvironmentSetupParticipant.
    def environment_created(self):
        pass

    def environment_needs_upgrade(self, db):
        cursor = db.cursor()

        # Is database up to date?
        upgradeneeded = self._get_db_version(cursor) != last_db_version
        if upgradeneeded:
            self.upgrade_environment(db)
        return False

    def upgrade_environment(self, db):
        cursor = db.cursor()

        # Get current database schema version.
        db_version = self._get_db_version(cursor)

        # Perform incremental upgrades.
        for I in range(db_version + 1, last_db_version + 1):
            script_name  = 'db%i' % (I)
            module = __import__('tracdiscussion.db.%s' % (script_name),
            globals(), locals(), ['do_upgrade'])
            module.do_upgrade(self.env, cursor)

        # import optional modules
        for module in self.additional_options:
            module = __import__('tracdiscussion.db.%s' % (str(module)),
                                globals(), locals(), ['do_upgrade'])
            module.do_upgrade(self.env, cursor)

        # Finish database changes.
        db.commit()

    def _get_db_version(self, cursor):
        try:
            sql = ("SELECT value "
                   "FROM system "
                   "WHERE name='discussion_version'")
            self.log.debug(sql)
            cursor.execute(sql)
            for row in cursor:
                return int(row[0])
            return 0
        except:
            return 0
